package com.zmj.sy.mom.srv.aps.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseResVo;
import com.zmj.sy.mom.srv.aps.utils.ControllerAspectIgnore;
import com.zmj.sy.mom.srv.aps.utils.SySecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Component
@Slf4j
@Aspect
@RequiredArgsConstructor
public class ControllerLogConfig {

    private final HttpServletRequest request;

    private final ObjectMapper objectMapper;

    @SuppressWarnings("all")
    @SneakyThrows
    @Around("execution(* com.zmj.sy.mom.srv.aps.controller.*Controller.*(..))")
    public Object around(ProceedingJoinPoint pjp) {

        String url = request.getRequestURI();
        String queryString = request.getQueryString();

        long start = System.currentTimeMillis();
        Object[] args = pjp.getArgs();

        Method method = getPjpMethod(pjp);
        ControllerAspectIgnore annotation = method.getAnnotation(ControllerAspectIgnore.class);//获得该注解
        Object result = null;

        boolean success = false;

        try {
            result = pjp.proceed();
            if (result instanceof BaseResVo) {
                ((BaseResVo) result).setCode(BaseResVo.SUCCESS_CODE);
            }

            success = true;
        } catch (Throwable e) {
            throw e;
        } finally {
            log.info("controller-log method: {}, url: {}, success: {}, user: {},time: {}, query: {}, request: {}, response: {} ",
                    request.getMethod(),
                    url,
                    success,
                    SySecurityUtils.getUserCode(),
                    System.currentTimeMillis() - start,
                    queryString,
                    annotation != null? "ignore" : (args == null ? null : objectMapper.writeValueAsString(args)),
                        annotation != null? "ignore" : (result == null ? null : objectMapper.writeValueAsString(result)));

        }
        return result;
    }


    /**
     * 获取反映的方法
     *
     */
    private static Method getPjpMethod(ProceedingJoinPoint pjp) throws NoSuchMethodException {
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Class<?> clazz = methodSignature.getDeclaringType();
        return clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}
